package encrypt

import (
	"bytes"
	"encoding/base64"
	"fmt"
	"io/ioutil"
	"net/http"
	"strconv"
	"strings"
	"time"
	"zzxq/common/codes"
	"zzxq/common/setting"

	"github.com/chentaihan/aesCbc"
	"github.com/gin-gonic/gin"
)

type EncryptKeyInfo struct {
	Key string //秘钥
	Iv  string //iv
}

func Encrypt(orginData string) string { //加密

	conf := setting.Config.GinFast
	encKeyInfo := EncryptKeyInfo{
		Key: conf.AESKey,
		Iv:  conf.AESIvData,
	}
	encrData := aesCbc.AesEncrypt([]byte(encKeyInfo.Key), []byte(encKeyInfo.Iv), []byte(orginData))
	return base64.URLEncoding.EncodeToString(encrData)
}

func Decrypt(encryptData string) ([]byte, error) { //解密

	conf := setting.Config.GinFast
	encKeyInfo := EncryptKeyInfo{
		Key: conf.AESKey,
		Iv:  conf.AESIvData,
	}
	tmp, err := base64.URLEncoding.DecodeString(encryptData)
	if err != nil {
		return []byte(""), err
	}
	return aesCbc.AesDecrypt([]byte(encKeyInfo.Key), []byte(encKeyInfo.Iv), tmp), nil
}

func ReqRspEncrypt(c *gin.Context) {
	//在gin上下文中定义一个变量
	body, err := ioutil.ReadAll(c.Request.Body)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": codes.ERRAES,
			"msg":  codes.GetMsg(codes.ERRAES),
		})
		c.Abort()
		return
	}
	encryptData := string(body)
	encryptData = strings.Replace(encryptData, "%3D", "", -1)
	encryptData = strings.Replace(encryptData, " ", "", -1)
	orignData, err := Decrypt(encryptData)
	if err != nil {
		fmt.Println("解密失败", err)
		c.JSON(http.StatusOK, gin.H{
			"code": codes.ERRAES,
			"msg":  codes.GetMsg(codes.ERRAES),
		})
		c.Abort()
		return
	}
	orignDataStr := strings.Replace(string(orignData), "\f", "", -1) //去除换页
	orignDataStr = strings.Replace(orignDataStr, "\x10", "", -1)     //去除数据链路转意符号
	c.Request.Body = ioutil.NopCloser(bytes.NewBuffer([]byte(orignDataStr)))
	var contentType []string
	contentType = append(contentType, "application/x-www-form-urlencoded")
	c.Request.Header["Content-Type"] = contentType

	timeStamp := c.PostForm("ts")
	if timeStamp == "" {
		c.JSON(http.StatusOK, gin.H{
			"code": codes.ERRAES,
			"msg":  codes.GetMsg(codes.ERRAES),
		})
		c.Abort()
		return
	}
	now := time.Now().Unix()
	timeStampInt, err := strconv.Atoi(timeStamp)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": codes.ERRAES,
			"msg":  codes.GetMsg(codes.ERRAES),
		})
		c.Abort()
		return
	}

	if timeStampInt > (int(now)+300) || timeStampInt < (int(now)-300) {
		c.JSON(http.StatusOK, gin.H{
			"code": codes.ERRAES,
			"msg":  codes.GetMsg(codes.ERRAES),
		})
		c.Abort()
		return
	}

	//请求之前
	c.Next()

	resp := c.MustGet("resp").(string)
	c.String(http.StatusOK, Encrypt(resp))
	c.Abort()
}
